package com.jtny.nytb.datafilling.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.jtny.component.dto.CurrentUserDTO;
import com.jtny.component.entity.LocalHolder;
import com.jtny.component.exception.ServiceException;
import com.jtny.component.util.BeanUtils;
import com.jtny.component.util.CurrentUserUtils;
import com.jtny.nytb.config.excel.util.EasyExcelUtils;
import com.jtny.nytb.datafilling.service.EnergyPriceTempService;
import com.jtny.nytb.datafilling.service.EnergyPriceTempletService;
import com.jtny.nytb.datafilling.vo.*;

import com.jtny.nytb.datafilling.dto.*;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 能源价格模板填报业务接口实现类，实现EnergyPriceTempletBiz
 *
 * @author 罗霄林
 * @package com.jtny.nytb.energymonitor.datafilling.biz.impl
 * @fileName EnergyPriceTempletBizImpl.java
 * @createTime 2023年09月06日 00:00
 */
@Service
public class EnergyPriceTempletServiceImpl implements EnergyPriceTempletService {

    @Autowired
    private EnergyPriceTempService energyPriceTempService;

    @Override
    public List<EnergyPriceTempletVO> queryEnergyPriceTempletInfo(EnergyPriceTempletParamVO energyPriceTempletParamVO) {
        EnergyPriceTempletParamDTO eptpDTO = new EnergyPriceTempletParamDTO();
        BeanUtils.copyObject(energyPriceTempletParamVO, eptpDTO);
        List<EnergyPriceTempletDTO> list = energyPriceTempService.queryEnergyPriceTempletInfo(eptpDTO);
        List<EnergyPriceTempletVO> eptList = new ArrayList<>();
        list.forEach(
                eptDTO -> {
                    EnergyPriceTempletVO eptVO = new EnergyPriceTempletVO();
                    BeanUtils.copyObject(eptDTO, eptVO);
                    List<DataVO> dataVOList = new ArrayList<>();
                    eptDTO.getDataList().forEach(
                            epDTO -> {
                                DataVO dataVO = new DataVO();
                                dataVO.setColumnValue(epDTO.getColumnValue() == null ? "0" : epDTO.getColumnValue().toPlainString());                                dataVO.setColumnName(epDTO.getColumnName());
                                dataVO.setEnergyModelId(epDTO.getEnergyModelId());
                                dataVOList.add(dataVO);
                            }
                    );
                    eptVO.setDataList(dataVOList);
                    if (StringUtils.isNotEmpty(eptDTO.getGroupName())) {
                        eptVO.setType("group");
                    } else {
                        eptVO.setType("name");
                    }
                    eptList.add(eptVO);
                }
        );
        return eptList;
    }

    @Override
    public Boolean saveEnergyPriceTempletData(EnergyPriceTempletParamVO energyPriceTempletParamVO) {
        EnergyPriceTempletParamDTO eptDTO = new EnergyPriceTempletParamDTO();
        BeanUtils.copyObject(energyPriceTempletParamVO, eptDTO);
        CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();
        CurrentUserUtils.setCreateDefaultField(eptDTO, currentUserDTO);
        if (ObjectUtils.isNotEmpty(energyPriceTempletParamVO.getDataList())) {
            eptDTO.setDataList(BeanUtils.copyToList(energyPriceTempletParamVO.getDataList(), EnergyPriceDTO.class));
            eptDTO.getDataList().forEach(
                    data -> {
                        CurrentUserUtils.setCreateDefaultField(data, currentUserDTO);
                    }
            );
        }
        return energyPriceTempService.saveEnergyPriceTempletData(eptDTO);
    }

    @Override
    public void modfiyEnergyPriceTempletData(EnergyPriceTempletParamVO energyPriceTempletParamVO) {
        EnergyPriceTempletParamDTO eptDTO = new EnergyPriceTempletParamDTO();
        BeanUtils.copyObject(energyPriceTempletParamVO, eptDTO);
        CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();
        CurrentUserUtils.setUpdateDefaultField(eptDTO, currentUserDTO);
        if (ObjectUtils.isNotEmpty(energyPriceTempletParamVO.getDataList())) {
            // 通过模板id查出价格表是否存在该数据
            List<EnergyModelPriceDTO> energyModelPriceDTOList = energyPriceTempService.getEnergyPrice(eptDTO.getId());
            eptDTO.setDataList(BeanUtils.copyToList(energyPriceTempletParamVO.getDataList(), EnergyPriceDTO.class));
            if (CollectionUtil.isNotEmpty(energyModelPriceDTOList)) {
                eptDTO.getDataList().forEach(
                        data -> {
                            CurrentUserUtils.setUpdateDefaultField(data, currentUserDTO);
                        }
                );
                energyPriceTempService.modfiyEnergyPriceTempletData(eptDTO);
            }else {
                // 取出需要存的价格表数据
                eptDTO.getDataList().forEach(a -> {
                    CurrentUserUtils.setCreateDefaultField(a,currentUserDTO);
                });
                energyPriceTempService.saveEnergyPrice(eptDTO);
            }
        }
    }

    @Override
    public Boolean delEnergyPriceTempletData(String id) {
        return energyPriceTempService.delEnergyPriceTempletData(id);
    }

    @Override
    public Map<String, List<String>> queryInstitution(String typeId) {
        return energyPriceTempService.queryInstitution(typeId);
    }

    @Override
    public NameOrGroupContentVO queryName(String typeId, String Institution) {
        NameOrGroupContentDTO dto = energyPriceTempService.queryNameByInstitutionAndType(typeId, Institution);
        return BeanUtils.copyToObject(dto, NameOrGroupContentVO.class);
    }


    @Override
    public Boolean importEnergyPriceTempletData(MultipartFile file, String typeId) throws IOException, InvocationTargetException, IllegalAccessException, InstantiationException {
        //读取Excel数据前两列
        ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
        reader.addHeaderAlias("制度", "institution");
        reader.addHeaderAlias("名称", "name");
        reader.addHeaderAlias("分组名称", "groupName");
        List<EnergyPriceTempletParamVO> energyModelList = reader.readAll(EnergyPriceTempletParamVO.class);
        if ("electric".equals(typeId)) {
            //用电数据信息
            reader.addHeaderAlias("电度用电价格", "usePrice");
            reader.addHeaderAlias("代理购电价格", "proxyPrice");
            reader.addHeaderAlias("电度输配电价", "transportPrice");
            reader.addHeaderAlias("政府性基金及附加", "govPrice");
            reader.addHeaderAlias("尖峰", "point");
            reader.addHeaderAlias("高峰", "high");
            reader.addHeaderAlias("平段", "even");
            reader.addHeaderAlias("低谷", "low");
            reader.addHeaderAlias("最大需量", "max");
            reader.addHeaderAlias("变压器容量", "transformerCapacity");
            List<ElectricImportVO> energyModelPriceList = reader.readAll(ElectricImportVO.class);
            for (int i = 0; i < energyModelList.size(); i++) {
                if ("/".equals(energyModelList.get(i).getGroupName())) {
                    energyModelList.get(i).setGroupName("");
                }
                energyModelList.get(i).setDataList(createDataVoList(ElectricImportVO.class, energyModelPriceList.get(i)));
                energyModelList.get(i).setTypeId("electric");
                energyModelList.get(i).setTypeName("电");
            }

        }
        if ("water".equals(typeId)) {
            reader.addHeaderAlias("自来水价格", "citywaterPrice");
            reader.addHeaderAlias("代收污水处理费", "sewagePrice");
            reader.addHeaderAlias("起始值", "start");
            reader.addHeaderAlias("截止值", "end");
            List<WaterImportVO> energyModelPriceList = reader.readAll(WaterImportVO.class);
            for (int i = 0; i < energyModelList.size(); i++) {
                if ("/".equals(energyModelList.get(i).getGroupName())) {
                    energyModelList.get(i).setGroupName("");
                }
                energyModelList.get(i).setDataList(createDataVoList(WaterImportVO.class, energyModelPriceList.get(i)));
                energyModelList.get(i).setTypeId("water");
                energyModelList.get(i).setTypeName("水");
            }
        }
        if ("gas".equals(typeId)) {
            reader.addHeaderAlias("销售价格", "salePrice");
            reader.addHeaderAlias("起始值", "start");
            reader.addHeaderAlias("截止值", "end");
            List<GasImportVO> energyModelPriceList = reader.readAll(GasImportVO.class);
            for (int i = 0; i < energyModelList.size(); i++) {
                if ("/".equals(energyModelList.get(i).getGroupName())) {
                    energyModelList.get(i).setGroupName("");
                }
                energyModelList.get(i).setDataList(createDataVoList(GasImportVO.class, energyModelPriceList.get(i)));
                energyModelList.get(i).setTypeId("gas");
                energyModelList.get(i).setTypeName("气");
            }
        }
        List<EnergyPriceTempletParamDTO> eptDTOList = BeanUtils.copyToList(energyModelList, EnergyPriceTempletParamDTO.class);
        eptDTOList.forEach(
                ept -> {
                    CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();
                    CurrentUserUtils.setCreateDefaultField(ept, currentUserDTO);
                    ept.getDataList().forEach(
                            ep -> {
                                CurrentUserUtils.setCreateDefaultField(ep, currentUserDTO);
                            }
                    );
                }
        );
        return energyPriceTempService.importEnergyPriceTempletData(eptDTOList);
    }

    /**
     * 使用反射生成DataVoList
     *
     * @param clazz
     * @param dataImportBaseVO
     * @return
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    private List<com.jtny.nytb.datafilling.vo.DataVO> createDataVoList(Class clazz, DataImportBaseVO dataImportBaseVO) throws InvocationTargetException, IllegalAccessException {
        List<com.jtny.nytb.datafilling.vo.DataVO> dataVOList = new ArrayList<>();
        //传入的类如果没继承数据导入父类 则返回空list
        if (!DataImportBaseVO.class.isAssignableFrom(clazz)) {
            return dataVOList;
        }
        //获取传入类的所有变量名称和所有方法
        Field[] field = clazz.getDeclaredFields();
        Method[] method = clazz.getMethods();
        for (Field f : field) {
            String name = f.getName().toUpperCase();
            for (Method m : method) {
                //循环变量名和方法名，获取变量的get方法并将其值传给dataVO，并生成DataVoList
                String mname = m.getName().toUpperCase();
                if (mname.contains(name) && mname.contains("GET")) {
                    DataVO dataVO = new DataVO();
                    dataVO.setColumnName(f.getName());
                    if ("/".equals((String) m.invoke(dataImportBaseVO))) {
                        //为空值时转换为0
                        dataVO.setColumnValue("0.0000000");
                    } else {
                        dataVO.setColumnValue((String) m.invoke(dataImportBaseVO));
                    }
                    dataVOList.add(dataVO);
                }
            }
        }
        return dataVOList;
    }

    private static final String ELECTRIC_CONSUMPTION_TEMPLATE = "能源价格模板（电）";
    private static final String WATER_CONSUMPTION_TEMPLATE = "能源价格模板（水）";
    private static final String GAS_CONSUMPTION_TEMPLATE = "能源价格模板（气）";

    @Override
    public void downloadPriceTemplate(HttpServletResponse response, String typeId) throws ServiceException {
        String fileName = "";
        Class clazz = null;
        if ("electric".equals(typeId)) {
            fileName = ELECTRIC_CONSUMPTION_TEMPLATE;
            clazz = ElectricExcelVO.class;
        } else if ("water".equals(typeId)) {
            fileName = WATER_CONSUMPTION_TEMPLATE;
            clazz = WaterExcelExcelVO.class;
        } else if ("gas".equals(typeId)) {
            fileName = GAS_CONSUMPTION_TEMPLATE;
            clazz = GasExcelExcelVO.class;
        } else {
            return;
        }
        EasyExcelUtils.exportExcel(response, fileName, null, clazz);
    }

    @Override
    public List<EnergyModelVO> getEnergyPriceTempletInfo(EnergyModelPriceParamVO energyModelPriceParamVO) {
        List<EnergyModelDTO> energyModelDTOS = energyPriceTempService.getEnergyPriceTempletInfo(BeanUtils.copyToObject(energyModelPriceParamVO, EnergyModelPriceParamDTO.class));
        return BeanUtils.copyToList(energyModelDTOS, EnergyModelVO.class);
    }

    @Override
    public void deleteEnergyTemplate(Long id) {
        if (id == null) {
            throw new ServiceException("id不能为空");
        }
        //获取当前登录用户
        CurrentUserDTO currentUserDTO = LocalHolder.getCurrentUser();
        List<EnergyModelPriceDTO> energyModelPriceDTOS = energyPriceTempService.seleteEnergyTemplatePrice(id);
        if (CollectionUtil.isEmpty(energyModelPriceDTOS)) {
            return;
        }
        energyModelPriceDTOS.forEach(a -> {
            CurrentUserUtils.setUpdateDefaultField(a, currentUserDTO);
        });
        energyPriceTempService.deleteEnergyTemplate(energyModelPriceDTOS);
    }

    @Override
    public List<EnergyModelVO> getEnergyTemplateInfo(Long id) {
        if (id == null) {
            throw new ServiceException("id不能为空");
        }
        List<EnergyModelDTO> energyModelVOList = energyPriceTempService.getEnergyTemplateInfo(id);
        return BeanUtils.copyToList(energyModelVOList, EnergyModelVO.class);
    }

    @Override
    public List<String> queryLevel(EnergyPriceTempletParamVO energyModelVO) {
        List<EnergyPriceTempletVO> energyPriceTempletVOS = queryEnergyPriceTempletInfo(energyModelVO);
        if(CollectionUtil.isEmpty(energyPriceTempletVOS)){
            return new ArrayList<>(0);
        }
        return energyPriceTempletVOS.stream().map(EnergyPriceTempletVO::getGroupName).collect(Collectors.toList());
    }

    @Override
    public List<String> queryElType(String typeId) {
        EnergyPriceTempletParamVO energyPriceTempletParamVO = new EnergyPriceTempletParamVO();
        energyPriceTempletParamVO.setTypeId(typeId);
        List<EnergyPriceTempletVO> energyPriceTempletVOS = queryEnergyPriceTempletInfo(energyPriceTempletParamVO);
        if(CollectionUtil.isEmpty(energyPriceTempletVOS)){
            return new ArrayList<>(0);
        }
        return energyPriceTempletVOS.stream().map(EnergyPriceTempletVO::getInstitution).collect(Collectors.toList());
    }

    @Override
    public void deleteEnergyTemplateById(Long id) {
        if (id == null) {
            throw new ServiceException("id不能为空");
        }
        energyPriceTempService.deleteEnergyTemplateById(id);
    }


}
